"""
用户相关Pydantic模式
创建时间：2025-09-12
作者：开发团队
目的：定义用户相关的数据验证和序列化模式
"""

from pydantic import BaseModel, Field, field_validator, ValidationInfo
from datetime import datetime


class UserBase(BaseModel):
    """用户基础模式"""
    username: str = Field(..., min_length=3, max_length=50)
    name: str = Field(..., min_length=1, max_length=100)
    phone: str | None = Field(None, max_length=20)
    campus_id: int | None = None


class UserCreate(UserBase):
    """用户创建模式"""
    password: str = Field(..., min_length=6, max_length=50)
    role: str = Field(..., pattern="^(guard|admin|superadmin)$")

    @field_validator('username')
    @classmethod
    def username_alphanumeric(cls, v: str) -> str:
        assert v.isalnum() or v.replace('_', '').isalnum(), '用户名只能包含字母、数字和下划线'
        return v


class UserUpdate(BaseModel):
    """用户更新模式"""
    name: str | None = Field(None, min_length=1, max_length=100)
    phone: str | None = Field(None, max_length=20)
    campus_id: int | None = None


class UserResponse(UserBase):
    """用户响应模式"""
    id: int
    role: str
    status: str
    last_login: datetime | None = None
    created_at: datetime
    # 根据API契约添加缺失的字段
    campus_name: str | None = None
    permissions: list[str] = []

    class Config:
        from_attributes = True


class Token(BaseModel):
    """令牌模式"""
    access_token: str
    token_type: str


class TokenData(BaseModel):
    """令牌数据模式"""
    username: str | None = None


class ChangePasswordRequest(BaseModel):
    """修改密码请求模式"""
    old_password: str = Field(..., min_length=6, max_length=50)
    new_password: str = Field(..., min_length=6, max_length=50)
    confirm_password: str = Field(..., min_length=6, max_length=50)

    @field_validator('confirm_password')
    @classmethod
    def passwords_match(cls, v: str, info: ValidationInfo) -> str:
        if 'new_password' in info.data and v != info.data['new_password']:
            raise ValueError('确认密码与新密码不匹配')
        return v


# 登录相关模式
class LoginRequest(BaseModel):
    """登录请求模式"""
    username: str = Field(..., min_length=3, max_length=20)
    password: str = Field(..., min_length=6, max_length=20)
    remember: bool | None = False


class LoginResponseData(BaseModel):
    """登录响应数据模式"""
    token: str
    user: UserResponse


class LoginResponse(BaseModel):
    """登录响应模式"""
    code: int
    message: str
    data: dict[str, object] | None = None
    error: str | None = None
    timestamp: datetime


class ApiResponse(BaseModel):
    """通用API响应模式"""
    code: int
    message: str
    data: dict[str, object] | None = None
    error: str | None = None
    timestamp: datetime